package org.hako.recite.word.test.impl.gui.swt;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.hako.recite.word.Constants;
import org.hako.recite.word.test.WordTestResource;
import org.hako.recite.word.test.impl.gui.NullWordTestBehavior;
import org.hako.recite.word.test.impl.gui.WordTestBehavior;

/**
 * Word test shell.
 * 
 * @since 0.4.3
 * @author <a href="mailto:xnnyygn@gmail.com">xnnyygn</a>
 */
public class WordTestShell extends AbstractReciteWordShell {

	private Text txtUserAnswer;
	private Label lbHint;
	private Label lbQuestion;
	private Label lbQuestionCounter;
	private WordTestResource resource;
	private int questionCount;
	private int currentIndex;
	private boolean showingHint;
	private MessageBox messageBox;

	/**
	 * Create
	 */
	WordTestShell() {
		this(null, new NullWordTestBehavior());
	}

	/**
	 * Create
	 * 
	 * @param parentShell
	 * @param behavior
	 *            TODO
	 */
	public WordTestShell(Shell parentShell, WordTestBehavior behavior) {
		super(parentShell, SWT.DIALOG_TRIM, behavior);
		this.behavior = behavior;
		shell.setText("Word Test");
		addComponenets(shell);
		shell.pack();
		shell.setSize(400, shell.getSize().y);
		center();
	}

	/**
	 * Add components to composite.
	 * 
	 * @param parentComposite
	 */
	private void addComponenets(Composite parentComposite) {
		FillLayout parentCompositeLayout = new FillLayout(SWT.VERTICAL);
		parentCompositeLayout.marginHeight = 10;
		parentCompositeLayout.marginWidth = 10;
		parentCompositeLayout.spacing = 5;
		parentComposite.setLayout(parentCompositeLayout);

		// add label question counter
		lbQuestionCounter = new Label(parentComposite, SWT.NONE);
		lbQuestionCounter.setText("Question counter");

		// add label question
		lbQuestion = new Label(parentComposite, SWT.NONE);
		lbQuestion.setText("Question");

		// add text user answer
		txtUserAnswer = new Text(parentComposite, SWT.SINGLE | SWT.BORDER);
		txtUserAnswer.addSelectionListener(new SelectionListener() {

			@Override
			public void widgetDefaultSelected(SelectionEvent event) {
				widgetSelected(event);
			}

			@Override
			public void widgetSelected(SelectionEvent event) {
				if (showingHint) {
					showNextQuestion();
					showingHint = false;
					return;
				}
				String userAnswer = txtUserAnswer.getText().trim();

				// check if user answer is blank
				if (userAnswer.length() == 0) {
					return;
				}

				String correctAnswer = resource.getAnswer(currentIndex);
				if (!correctAnswer.equals(userAnswer)) {
					resource.addWrong(currentIndex);
					lbHint.setText(correctAnswer);
					showingHint = true;
				} else {
					showNextQuestion();
				}
			}

		});

		// add label hint
		lbHint = new Label(parentComposite, SWT.NONE);
		lbHint.setText("Hint");
	}

	/**
	 * Show shell and start test.
	 * 
	 * @param resource
	 */
	public void show(WordTestResource resource) {
		this.resource = resource;
		questionCount = resource.getQuestionCount();
		currentIndex = 0;
		showingHint = false;
		showQuestion(currentIndex);

		// show shell
		show();
	}

	/**
	 * Show next question.
	 */
	private void showNextQuestion() {
		currentIndex++;
		if (currentIndex < questionCount) {
			showQuestion(currentIndex);
		} else {

			// show result
			MessageBox messageBox = getMessageBox();
			messageBox.setMessage(resource.generateWrongWordsReport());
			messageBox.open();

			// finish test
			behavior.finishTest();
		}
	}

	/**
	 * Get messageBox.
	 * 
	 * @return
	 */
	private MessageBox getMessageBox() {
		if (messageBox == null) {
			messageBox = new MessageBox(shell, SWT.ICON_INFORMATION | SWT.OK);
			messageBox.setText(Constants.APPLICATION_NAME + ' '
					+ Constants.VERSION);
		}
		return messageBox;
	}

	/**
	 * Show question.
	 * 
	 * @param index
	 */
	private void showQuestion(int index) {

		// setup question counter
		lbQuestionCounter.setText((index + 1) + "/" + questionCount);

		// setup question
		lbQuestion.setText(resource.getQuestion(index));

		// setup user answer
		txtUserAnswer.setText("");

		// setup hint
		lbHint.setText("");
	}

}
